package com.ctshk.rpc.scenic.service.impl.app;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ctshk.common.constant.ElasticSearchConstant;
import com.ctshk.common.constant.RedisConstants;
import com.ctshk.rpc.scenic.dto.app.ScenicProductTypeDTO;
import com.ctshk.rpc.scenic.dto.app.ScenicProductTypeListDTO;
import com.ctshk.rpc.scenic.mapper.app.ScenicProductTypeMapper;
import com.ctshk.rpc.scenic.service.app.IScenicProductTypeService;
import org.apache.dubbo.config.annotation.DubboService;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@DubboService
public class ScenicProductTypeServiceImpl implements IScenicProductTypeService {
    @Autowired
    RedisTemplate<String, String> redisTemplate;
    @Autowired
    ScenicProductTypeMapper scenicProductTypeMapper;
    @Autowired
    RestHighLevelClient restHighLevelClient;

    @Override
    public List<ScenicProductTypeListDTO> selectScenicProductTypeList() {
        List<ScenicProductTypeListDTO> scenicProductTypeListDTOS = new ArrayList<>();
        String s = redisTemplate.opsForValue().get(RedisConstants.SCENIC_PRODUCT_TYPE_LIST);
        if(s == null){
            List<ScenicProductTypeDTO> scenicProductTypeDTOS = scenicProductTypeMapper.selectScenicProductTypeList();
            for (ScenicProductTypeDTO scenicProductTypeDTO : scenicProductTypeDTOS) {
                ScenicProductTypeListDTO scenicProductTypeListDTO = new ScenicProductTypeListDTO();
                scenicProductTypeListDTO.setTitle(scenicProductTypeDTO.getName());
                {// 解析图片
                    String photos = scenicProductTypeDTO.getPhotos();
                    if(photos != null && !photos.trim().equals("")){
                        List<JSONObject> jsonObjects = JSON.parseArray(photos, JSONObject.class);
                        for (JSONObject jsonObject : jsonObjects) {
                            Object url = jsonObject.get("url");
                            if(url != null){
                                scenicProductTypeListDTO.setIcon((String)url);
                                scenicProductTypeListDTOS.add(scenicProductTypeListDTO);
                                break;
                            }
                        }
                    }
                }
            }
            // 写出到Redis中 5-25分钟失效
            int time = 5 + new Random().nextInt(15);
            try{
                redisTemplate.opsForValue().set(RedisConstants.SCENIC_PRODUCT_TYPE_LIST, JSON.toJSONString(scenicProductTypeListDTOS), time, TimeUnit.MINUTES);
            }catch (Exception e){
                e.printStackTrace();
                return new ArrayList<>();
            }
        }else{
            scenicProductTypeListDTOS = JSON.parseArray(s, ScenicProductTypeListDTO.class);
        }
        List<ScenicProductTypeListDTO> result = new ArrayList<>();
        {// 验证分类下是否有数据，不返回空数据的分类
            for (ScenicProductTypeListDTO scenicProductTypeListDTO : scenicProductTypeListDTOS) {
                SearchRequest searchRequest = new SearchRequest(ElasticSearchConstant.SCENIC);
                SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
                searchSourceBuilder.from(0);
                searchSourceBuilder.size(1);
                BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
                boolQueryBuilder.filter(QueryBuilders.termQuery("productTypeName.keyword", scenicProductTypeListDTO.getTitle()));
                searchSourceBuilder.query(boolQueryBuilder);
                searchRequest.source(searchSourceBuilder);
                long hitsValue = 0;
                try {
                    SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
                    hitsValue = search.getHits().getTotalHits().value;
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if(hitsValue > 0){
                    result.add(scenicProductTypeListDTO);
                }
            }
        }
        return result;
    }
}
